﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ViewModelRegistrationConvention.cs" company="Marcin Jastrzebski">
//   Copyright (c) Marcin Jastrzebski (marcin@marcinj.net)
// </copyright>
// <summary>
//   The view model registration convention.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace mPassRT.ViewModels
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    using Microsoft.Practices.Unity;

    using mPassRT.Common;

    /// <summary>The view model registration convention.</summary>
    internal class ViewModelRegistrationConvention : RegistrationConvention
    {
        #region Constants

        /// <summary>The page suffix.</summary>
        private const string PageSuffix = "Page";

        /// <summary>The view model suffix.</summary>
        private const string ViewModelSuffix = "ViewModel";

        #endregion

        #region Public Methods and Operators

        /// <summary>Converts page name to view model name.</summary>
        /// <param name="pageName">The page name.</param>
        /// <returns>The view model name.</returns>
        public static string PageToViewModel(string pageName)
        {
            return StripSuffix(pageName, PageSuffix) + ViewModelSuffix;
        }

        /// <summary>Converts the view model name to page name.</summary>
        /// <param name="viewModelName">The view model name.</param>
        /// <returns>The page name.</returns>
        public static string ViewModelToPage(string viewModelName)
        {
            return StripSuffix(viewModelName, ViewModelSuffix) + PageSuffix;
        }

        /// <summary>Gets the "from" types.</summary>
        /// <returns>Function mapping type to a list of "from" types.</returns>
        public override Func<Type, IEnumerable<Type>> GetFromTypes()
        {
            return _ => new[] { typeof(IPageViewModel) };
        }

        /// <summary>Gets injection members.</summary>
        /// <returns>Function mapping type to InjectionMember array.</returns>
        public override Func<Type, IEnumerable<InjectionMember>> GetInjectionMembers()
        {
            return _ => new InjectionMember[0];
        }

        /// <summary>Gets lifetime managers.</summary>
        /// <returns>The function mapping type to a lifetime manager.</returns>
        public override Func<Type, LifetimeManager> GetLifetimeManager()
        {
            return _ => new TransientLifetimeManager();
        }

        /// <summary>Gets registration name.</summary>
        /// <returns>The function mapping type to a registration name.</returns>
        public override Func<Type, string> GetName()
        {
            return type => type.Name;
        }

        /// <summary>The get types.</summary>
        /// <returns>Collection of types to register in the container.</returns>
        public override IEnumerable<Type> GetTypes()
        {
            IList<Type> types =
                AllClasses.FromApplication(false, false)
                          .Where(type => type.GetTypeInfo().IsSubclassOf(typeof(PageViewModel)))
                          .ToList();
            return types;
        }

        #endregion

        #region Methods

        /// <summary>Strips the specified suffix from the specified text if possible.</summary>
        /// <param name="text">The text.</param>
        /// <param name="suffix">The suffix.</param>
        /// <returns>The text with the suffix stripped if it was present.</returns>
        private static string StripSuffix(string text, string suffix)
        {
            return text.EndsWith(suffix) ? text.Remove(text.Length - suffix.Length) : text;
        }

        #endregion
    }
}